<?php

declare(strict_types=1);
/**
 * This file is part of Hyperf.
 *
 * @link     https://www.hyperf.io
 * @document https://hyperf.wiki
 * @contact  group@hyperf.io
 * @license  https://github.com/hyperf/hyperf/blob/master/LICENSE
 */
use App\Model\ChatRoomAuth;
use App\Model\User;
use App\Service\ApiDao\ConfigDao;
use App\Service\ApiDao\SpecialIdConfigDao;
use App\Service\ApiDao\SpecialRoomIdConfigDao;
use App\Service\Dao\AdminConfigDao;
use GuzzleHttp\Client;
use Hyperf\AsyncQueue\Driver\DriverFactory;
use Hyperf\AsyncQueue\Driver\DriverInterface;
use Hyperf\Database\Model\Builder;
use Hyperf\Guzzle\ClientFactory;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\Logger\LoggerFactory;
use Hyperf\Redis\Redis;
use Hyperf\Utils\ApplicationContext;
use Psr\Log\LoggerInterface;

if (! function_exists('di')) {
    /**
     * di.
     *
     * @return mixed
     */
    function di(string $id)
    {
        return ApplicationContext::getContainer()->get($id);
    }
}

if (! function_exists('getConfig')) {
    /**
     * 获取配置.
     *
     * @param null $default
     * @return mixed
     */
    function getConfig(string $name, $default = null)
    {
        try {
            $configs = di(AdminConfigDao::class)->get($name);
            if (! empty($configs)) {
                return $configs;
            }
            return config($name, $default);
        } catch (Exception $e) {
            return $default;
        }
    }
}

if (! function_exists('getApiConfig')) {
    /**
     * 获取配置.
     *
     * @param null $default
     * @param mixed $packageId
     * @return mixed
     */
    function getApiConfig(string $name, $default = null, $packageId = 0)
    {
        try {
            $configs = di(ConfigDao::class)->getV2($name, $packageId);
            if ($configs !== false) {
                return $configs;
            }
            return config($name, $default);
        } catch (Exception $e) {
            return $default;
        }
    }
}

if (! function_exists('filterPostString')) {
    function filterPostString(string $string): string
    {
        $string_old = $string;

        $string = str_ireplace('\\', '/', $string);

        $string = str_ireplace('"', '/', $string);

        $string = str_ireplace("'", '/', $string);

        $string = str_ireplace('*', '/', $string);

        $string = str_ireplace('%5C', '/', $string);

        $string = str_ireplace('%22', '/', $string);

        $string = str_ireplace('%27', '/', $string);

        $string = str_ireplace('%2A', '/', $string);

        $string = str_ireplace('~', '/', $string);

        $string = str_ireplace('select', "\\sel\ect", $string);

        $string = str_ireplace('insert', "\\ins\ert", $string);

        $string = str_ireplace('update', '\\up\\date', $string);

        $string = str_ireplace('delete', '\\de\\lete', $string);

        $string = str_ireplace('union', '\\un\\ion', $string);

        $string = str_ireplace('into', "\\in\to", $string);

        $string = str_ireplace('load_file', "\\load\\_\file", $string);

        $string = str_ireplace('outfile', "\\out\file", $string);

        $string = str_ireplace('sleep', "\\sle\ep", $string);

        $string = strip_tags($string);

        if ($string_old !== $string) {
            $string = '';
        }

        return trim($string);
    }
}

if (! function_exists('label_map')) {
    function labelMap(string $tag): array
    {
        return [];
    }
}

if (! function_exists('takeMold')) {
    /**
     * 取模
     */
    function takeMole(int $id): int
    {
        return $id % 10;
    }
}

/*
 *  日志
 */
if (! function_exists('logger')) {
    function logger(string $channel, string $name = 'log'): LoggerInterface
    {
        return di(LoggerFactory::class)->get($name, $channel);
    }
}

if (! function_exists('guzzle')) {
    function guzzle(): Client
    {
        return di(ClientFactory::class)->create();
    }
}

/*
 * 数组转化维xml
 *
 * @param $arr
 * @return string
 */
if (! function_exists('arrayToXml')) {
    function arrayToXml(array $arr): string
    {
        $xml = '<xml>';
        foreach ($arr as $key => $val) {
            if (is_numeric($val)) {
                $xml .= "<{$key}>{$val}</{$key}>";
            } else {
                $xml .= "<{$key}><![CDATA[{$val}]]></{$key}>";
            }
        }
        $xml .= '</xml>';
        return $xml;
    }
}

/*
 * xml转化为数组
 *
 * @param string $str
 * @return mixed
 */
if (! function_exists('xmlToArray')) {
    function xmlToArray(string $str)
    {
        $xml_parser = xml_parser_create();
        if (! xml_parse($xml_parser, $str, true)) {
            xml_parser_free($xml_parser);
            return false;
        }
        return json_decode(json_encode(simplexml_load_string($str, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
    }
}

/*
 * 获取随机字符串
 * @param int $randLength 长度
 * @param int $addTime
 * @param int $includeNumber
 * @return string
 */
if (! function_exists('randStr')) {
    function randStr($randLength = 6, $addTime = 1, $includeNumber = 1): string
    {
        mt_srand();
        if ($includeNumber) {
            $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQEST123456789';
        } else {
            $chars = 'abcdefghijklmnopqrstuvwxyz';
        }
        $len = strlen($chars);
        $randStr = '';
        for ($i = 0; $i < $randLength; ++$i) {
            $randStr .= $chars[random_int(0, $len - 1)];
        }
        return $addTime === 1 ? $randStr . time() : $randStr;
    }
}

if (! function_exists('retainDecimalPoint')) {
    /**
     * 保留小数点.
     * @param mixed $num
     */
    function retainDecimalPoint($num, int $accuracy = 2): float
    {
        if (empty($num)) {
            return floatval(0);
        }
        $num = sprintf('%.' . $accuracy . 'f', substr(sprintf('%.' . ($accuracy + 1) . 'f', floatval($num)), 0, -1));
        return floatval($num);
    }
}

/*
 * 数据查询
 *
 * @param string $str
 * @return Builder|false
 */
if (! function_exists('modelSearchFiled')) {
    function modelSearchFiled($model, array $filedArr, array $params, $fromUserColumns = '', $toUserColumns = '', $roomColumns = '')
    {
        // 查找用户编号
        $findShowNumber = [];
        if (isset($params['verification'])) {
            return false;
        }
        if (isset($params['show_number']) && ! empty($params['show_number'])) {
            $fromSpecId = ApplicationContext::getContainer()->get(SpecialIdConfigDao::class)->get($params['show_number']);
            if ($fromSpecId != -1) {
                if ($fromSpecId == 0) {
                    return false;
                }
                $filedArr[$fromUserColumns] = ['=', 'integer'];
                $params[$fromUserColumns] = (int) $fromSpecId;
            } else {
                if (! is_numeric($params['show_number'])) {
                    return false;
                }
                $findShowNumber[$params['show_number']] = 1;
            }
        }
        if (isset($params['to_show_number']) && ! empty($params['to_show_number'])) {
            $toSpecId = ApplicationContext::getContainer()->get(SpecialIdConfigDao::class)->get($params['to_show_number']);
            if ($toSpecId != -1) {
                if ($toSpecId == 0) {
                    return false;
                }
                $filedArr[$toUserColumns] = ['=', 'integer'];
                $params[$toUserColumns] = (int) $toSpecId;
            } else {
                if (! is_numeric($params['to_show_number'])) {
                    return false;
                }
                $findShowNumber[$params['to_show_number']] = 2;
            }
        }
        if (isset($params['room_number']) && ! empty($params['room_number'])) {
            $roomSpecId = ApplicationContext::getContainer()->get(SpecialRoomIdConfigDao::class)->get($params['room_number']);
            if ($roomSpecId != -1) {
                if ($roomSpecId == 0) {
                    return false;
                }
                $filedArr[$roomColumns] = ['=', 'integer'];
                $params[$roomColumns] = (int) $roomSpecId;
            } else {
                if (! is_numeric($params['room_number'])) {
                    return false;
                }
                $roomInfo = ChatRoomAuth::query()->where('show_number', $params['room_number'])->first(['id']);
                if (empty($roomInfo)) {
                    return false;
                }
                $filedArr[$roomColumns] = ['=', 'integer'];
                $params[$roomColumns] = (int) $roomInfo->id;
            }
        }
        if (! empty($findShowNumber)) {
            $userIds = User::query()->whereIn('show_number', array_keys($findShowNumber))->get([
                'id',
                'show_number',
            ])->toArray();
            if (empty($userIds)) {
                return false;
            }
            $userIds = array_column($userIds, 'id', 'show_number');
            foreach ($findShowNumber as $k => $v) {
                if (! isset($userIds[$k])) {
                    return false;
                }
                if ($v == 1) {
                    $filedArr[$fromUserColumns] = ['=', 'integer'];
                    $params[$fromUserColumns] = (int) $userIds[$k];
                }
                if ($v == 2) {
                    $filedArr[$toUserColumns] = ['=', 'integer'];
                    $params[$toUserColumns] = (int) $userIds[$k];
                }
            }
        }
        foreach ($filedArr as $key => $v) {
            if (! isset($params[$key]) || empty($params[$key])) {
                continue;
            }
            $argv = $params[$key];

            if ($v[1] == 'integer') {
                $argv = (int) $argv;
            } elseif ($v[1] == 'string') {
                $argv = trim($argv);
            } elseif ($v[1] == 'date') {
                //                if (!is_string($argv)) {
                //                    continue;
                //                }
                //                $argv = explode('~', $argv);
                // 上面注释条件是原来的
                if (is_string($argv)) {
                    continue;
                }

                if (count($argv) != 2) {
                    continue;
                }
                if (empty(strtotime($argv[0]))) {
                    continue;
                }
                if (empty(strtotime($argv[1]))) {
                    continue;
                }
                $model = $model->whereBetween($key, [
                    $argv[0], $argv[1],
                ]);
                continue;
            }
            if ($v[0] == 'like') {
                $argv = $argv . '%';
            }
            $model = $model->where($key, $v[0], $argv);
        }
        return $model;
    }
}

/*
 * 队列
 */
if (! function_exists('asyncQueue')) {
    function asyncQueue(string $channel = 'default'): DriverInterface
    {
        return di(DriverFactory::class)->get($channel);
    }
}

/*
 * 数据查询
 *
 * @param string $str
 * @return Builder|false
 */
if (! function_exists('getRoomByShowNumber')) {
    function getRoomByShowNumber(string $showNumber)
    {
        $fromSpecId = ApplicationContext::getContainer()->get(SpecialIdConfigDao::class)->get($showNumber);
        if ($fromSpecId != -1) {
            if ($fromSpecId == 0) {
                return false;
            }
            $userId = $fromSpecId;
        } else {
            $user = User::query()->where('show_number', $showNumber)->first([
                'id',
            ]);
            if (empty($user)) {
                return false;
            }
            $userId = $user->id;
        }
        $roomInfo = ChatRoomAuth::query()->where('user_id', $userId)->first(['id']);
        if (empty($roomInfo)) {
            return false;
        }
        return $roomInfo->id;
    }
}

if (! function_exists('getConfigVersion')) {
    /**
     * 获取配置版本.
     */
    function getConfigVersion(int $code): int
    {
        return (int) di(Redis::class)->get('system:config:' . $code);
    }
}

if (! function_exists('scriptCheck')) {
    /**
     * 脚本敏感字符处理.
     *
     * @return bool
     */
    function scriptCheck(string $str)
    {
        $str = strtolower($str);
        if (mb_strpos($str, 'script') === false) {
            if (mb_strpos($str, 'sql') === false) {
                return true;
            }
            return false;
        }
        return false;
    }
}
if (! function_exists('getConfigVersion')) {
    /**
     * 获取配置版本.
     */
    function getConfigVersion(int $code): int
    {
        return (int) di(Redis::class)->get('system:config:' . $code);
    }
}

if (! function_exists('setConfigVersion')) {
    /**
     * 获取配置版本.
     *
     * @param int $code 1=刷新礼物;2=刷新配置;3=道具库;4=国家;5=勋章;6=轮播图
     * @throws RedisException
     */
    function setConfigVersion(int $code)
    {
        di(Redis::class)->incr('system:config:' . $code);
    }
}

if (! function_exists('getIpAddress')) {
    /**
     * 获取id.
     */
    function getIpAddress(bool $toString = false): string
    {
        if (! $toString) {
            return ip2long(di(RequestInterface::class)->getHeaderLine('x-real-ip'));
        }
        return di(RequestInterface::class)->getHeaderLine('x-real-ip');
    }

    /*
     * 加密
     */
    if (! function_exists('encryptPhone')) {
        function encryptPhone(string $mark)
        {
            if (empty($mark)) {
                return '';
            }
            return openssl_encrypt($mark, 'DES-ECB', env('OPEN_SSL_PHONE'), 0);
        }
    }
}
